﻿/*
SINACOR - BMF&Bovespa
Arquivo: AberturaMovimentoBolsa.cs
Criado em: 17-mar-2010 16:37:58
Arquiteto Responsável: p-Wgeneroso
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sinacor.Infra.Core.ProcessManager.Server;
using Sinacor.Infra.Common.Exceptions;
using Sinacor.Infra.Service.ExceptionHandling;
using PSE.ProcessManager.Common.Process;
using Sinacor.Infra.Core.ProcessManager.Server.Security;
using PSE.ProcessManager.Server.Process.Security;


namespace Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.ProcessLogic
{
    public class AberturaMovimentoBolsa : BaseProcessLogic
    {


        #region Campos
        private int _erroMovimentoBolsasAberto = 109674;
        private int _erroMovimentoOrdensFechado = 109676;
        private int _erroNaoEsperado = 109677;
        private int _erroSemPermissaoAcesso = 109675;
        #endregion

        #region Propriedades

        public int ErroMovimentoBolsasAberto
        {
            get { return _erroMovimentoBolsasAberto; }
            set { _erroMovimentoBolsasAberto = value; }
        }


        public int ErroMovimentoOrdensFechado
        {
            get { return _erroMovimentoOrdensFechado; }
            set { _erroMovimentoOrdensFechado = value; }
        }


        public int ErroNaoEsperado
        {
            get { return _erroNaoEsperado; }
            set { _erroNaoEsperado = value; }
        }


        public int ErroSemPermissaoAcesso
        {
            get { return _erroSemPermissaoAcesso; }
            set { _erroSemPermissaoAcesso = value; }
        }
        #endregion

        #region Métodos
        /// <summary>
        /// Abre o movimento da Bolsa
        /// </summary>
        public ProcessEntity.ControleMovimento AbrirMovimento()
        {
            ResourceAccess.AberturaMovimentoBolsa resourceAccessAberturaMovimentoBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.ResourceAccess.AberturaMovimentoBolsa();
            ProcessEntity.Resultado resultadoAbertura = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.ProcessEntity.Resultado();
            if (this.VerificarPermissaoAcesso())
            {
                if (this.VerificarMovimentoFechado())
                {
                    if (this.VerificarModuloOrdensInstalado())
                    {
                        if (!this.VerificarMovimentoOrdensAberto())
                        {
                            throw new BusinessException(ErroMovimentoOrdensFechado);
                        }
                    }
                    try
                    {
                        resultadoAbertura = resourceAccessAberturaMovimentoBolsa.AbrirMovimento();
                        if (resultadoAbertura.Sucesso)
                        {
                            resourceAccessAberturaMovimentoBolsa.AtualizarMovimentoAberto();
                            return (ProcessEntity.ControleMovimento)resultadoAbertura.Valor;
                        }
                        else if (resultadoAbertura.CodigoErro == -1)
                        {
                            throw new BusinessException(ErroNaoEsperado);
                        }
                        else
                        {
                            this.TratarExcecoes(resultadoAbertura);
                        }
                    }
                    catch (Exception)
                    {
                        throw new BusinessException(ErroNaoEsperado);
                    }
                }
                else
                {
                    throw new BusinessException(ErroMovimentoBolsasAberto);
                }

            }
            else
            {
                throw new BusinessException(ErroSemPermissaoAcesso);
            }
            return (ProcessEntity.ControleMovimento)resultadoAbertura.Valor;
        }

        /// <summary>
        /// Trata as exceções geradas na execução da abertura.
        /// </summary>
        /// <param name="entity"></param>
        private void TratarExcecoes(ProcessEntity.Resultado entity)
        {
            if (entity != null)
            {
                if (entity.Argumentos != null)
                {
                    ErrorMessage.ConvertXmlArgumentsToParameters(entity.Argumentos);
                    throw new BusinessException(ErroNaoEsperado);
                }
                else
                {
                    throw new BusinessException(ErroNaoEsperado);
                }
            }        }

        /// <summary>
        /// Verifica se o usuário possui o módulo de ordens instalado.
        /// </summary>
        private bool VerificarModuloOrdensInstalado()
        {
            return (new Communication.Acesso()).VerificarSistemaInstalado("ORD");

            //Checar se o usuário possui instalado o
            //modulo de Ordens Bovespa, consumindo o
            //método "VerificarModuloOrdensInstalado", do
            //AuthorizationContext do processo em
            //execução, passando como parametro "ORD".
            //
            //
        }

        /// <summary>
        /// Verifica se o movimento de bolsas está fechado.
        /// </summary>
        private bool VerificarMovimentoFechado()
        {
            ProcessEntity.InformacoesMovimento informacoesMovimento = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.ProcessEntity.InformacoesMovimento();

            Communication.ControleMovimentoBolsa controleMovimentoBolsa = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.Communication.ControleMovimentoBolsa();
            informacoesMovimento = controleMovimentoBolsa.ObterInformacoesMovimento((new ProcessEntity.DataMovimento()));

            if (informacoesMovimento.EstadoMovimento == ProcessEntity.Enum.TipoMovimento.Fechado || informacoesMovimento.EstadoMovimento == Sinacor.Process.Bovespa.ControleMovimentoBolsa.ProcessEntity.Enum.TipoMovimento.AtualizandoVersao)
            {
                return true;
            }
            else
            {
                return false;
            }

            //1. Obter informações do movimento,
            //consumindo o método Communication.
            //ControleMovimentoBolsas.
            //ObterInformacoesMovimento() informando
            //no parametro a entidade vazia.
            //
            //Exemplo:
            //informacoesMovimento = Communication.
            //ControleMovimentoBolsas.
            //ObterInformacoesMovimento(new
            //ProcessEntity.DataMovimento());
            //
            //2. Verificar se o estado do movimento
            //está fechado ou atualizando versão.
            //
            //Se informacoesMovimento.EstadoMovimento
            //igual a TipoMovimento.Fechado .ou.
            //informacoesMovimento.EstadoMovimento
            //igual a TipoMovimento.AtualizandoVersao
            // Retornar verdadeiro.
            //SeNao
            // Retornar falso.
            //FimSe
        }

        /// <summary>
        /// Verifica se o movimento de ordens está aberto.
        /// </summary>
        private bool VerificarMovimentoOrdensAberto()
        {
            ProcessEntity.InformacoesMovimento informacoesMovimento = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.ProcessEntity.InformacoesMovimento();

            Communication.ControleMovimentoOrdens controleMovimentoOrdens = new Sinacor.Process.Bovespa.ControleMovimentoBolsa.Server.Communication.ControleMovimentoOrdens();
            informacoesMovimento = controleMovimentoOrdens.ObterInformacoesMovimento(new Sinacor.Process.Bovespa.ControleMovimentoBolsa.ProcessEntity.DataMovimento());
            if (informacoesMovimento.EstadoMovimento == ProcessEntity.Enum.TipoMovimento.Aberto)
            {
                return true;
            }
            else
            {
                return false;
            }
            //ObterInformacoesMovimento() informando
            //no parametro a entidade vazia.
            //
            //2. Verificar se o estado do movimento
            //obtido na ação anterior está aberto,
            //caso sim, retornar verdadeiro, caso
            //contrário falso.
            //
            //Exemplo:
            //informacoesMovimento = Communication.
            //ControleMovimentoOrdens.
            //ObterInformacoesMovimento(new
            //ProcessEntity.DataMovimento());
            //return (informacoesMovimento.
            //EstadoMovimento == TipoMovimento.
            //Aberto);



        }

        /// <summary>
        /// Verificar se o usuário possui acesso para abrir o movimento.
        /// </summary>
        private bool VerificarPermissaoAcesso()
        {
            //Checar se o usuário possui acesso na
            //função "BABERT"
            if (!AuthorizationContext<SinacorAuthorizationContext>.Current.CheckUserAccess("BABERT", "BOL"))
            {
                throw new BusinessException(ErroSemPermissaoAcesso);
            }
            return true;
        }
        #endregion
    }

}